Linux 您所在的位置:网站首页 linux input系统 Linux

Linux

2023-12-04 11:24| 来源: 网络整理| 查看: 265

一、input子系统         一、input子系统简介

                1、input子系统是用于管理输入的子系统,是linux内核为了处理某一类设备的一种框架,这一类设备就是输入设备。

                2、由于输入设备的种类有许许多多,不同的输入设备对应的输入信息不同,应用层中的处理方法也会有所不同,写驱动的时候只需要按要求上报输入事件。

                3、input子系统可以分为input驱动层、input核心层、input事件处理层,还要提供给用户空间访问的设备节点。

        二、驱动编写流程

                input核心层会向linux内核注册一个字符设备,可以在板上linux系统内的sys/class目录下查看到有input文件夹。input子系统的所有设备的主设备号都是13,使用input子系统不需要去注册字符设备只需要注册一个input_device。

                1、使用input子系统只需要注册一个inout设备使用起来十分方便,使用的是定义在内核文件include/linux/input.h中的input_dev结构体,以此来表示input设备,结构体定义部分如下:

struct input_dev { const char *name; const char *phys; const char *uniq; struct input_id id; unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //事件类型 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; //按价值 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; //相对坐标 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; //绝对坐标 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; //杂项事件 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; //LED事件 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; //sound相关 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; //压力反馈相关 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; //开关状态 unsigned int hint_events_per_packet; unsigned int keycodemax; unsigned int keycodesize; void *keycode; //省略其余代码 }

               2、在input_dev结构体中定义了许多了的位图,上图中的evbit[BITS_TO_LONGS(EV_CNT)]是表示事件类型的位图,evbit表示输入事件类型,输入事件的类型可在内核代码include/upai/linux/input.h中找到定义:

#define EV_SYN 0x00 //同步事件 #define EV_KEY 0x01 //按键事件 #define EV_REL 0x02 //相对坐标事件 #define EV_ABS 0x03 //绝对坐标事件 #define EV_MSC 0x04 //杂项事件 #define EV_SW 0x05 //开关事件 #define EV_LED 0x11 //LED事件 #define EV_SND 0x12 //sound事件 #define EV_REP 0x14 //重复事件 #define EV_FF 0x15 //压力事件 #define EV_PWR 0x16 //电源事件 #define EV_FF_STATUS 0x17 //压力状态事件

                3、使用input_allocate_device函数申请一个input_dev,函数返回值就是是申请到的input_dev。函数原型为:

struct input_dev *input_allocate_device(void)

                4、使用input_free_device函数释放申请到的input_dev,函数无返回值,函数原型为:

void input_free_device(struct input_dev *dev)

                5、申请一个input_dev以后就需要初始化,初始化的内容主要涉及两种,一种是事件类型(evbit)另一种是事件值(keybit)这两种。

                6、初始化后需要向内核注册,使用函数input_register_device,函数返回值为0表示注册成功,反之,函数参数为需要注册的input_dev。

int input_register_device(struct input_dev *dev)

                7、注销input驱动使用函数input_unregister_device注销input_dev,函数无返回值,参数为要注销的input_dev。

void input_unregister_device(struct input_dev *dev)

                8、总结:

                                1)使用input_allocate_device函数申请一个input_dev

                                2)初始化申请到的input_dev,包括事件类型与事件值

                                3)使用input_register_device函数向linux内核注册前面初始化的input_dev

                                4)卸载要先使用input_unregister_device函数注销input_dev,然后使用input_free_device函数释放申请的input_dev。

        三、输入事件的上报

                1、注册好input_dev以后还需要告诉内核输入事件是什么亦或是输入值是什么,需要将这些相关的信息上报给内核,内核才可以获取到正确的输入值,不同输入事件使用的API函数不同。

                2、使用函数input_event函数上报指定的事件以及对应的值,此函数可以上报所有的事件类型与事件值,函数原型为:

void input_event(struct input_dev *dev, //需要上报的input_dev unsigned int type, //上报的类型 unsigned int code, //事件码 int value) //事件值

                3、上报事件后还需要使用函数input_sync函数通知内核input子系统上报完毕,参数是需要上报同步事件的input_dev,函数原型为:

void input_sync(struct input_dev *dev)         四、input_event结构体的作用

                1、Linux内核中是用input_event结构体来表示所有输入事件的,用户应用程序通过input_event获取具体的输入事件及其值,结构体定义在内核文件中include/uapi/linux/input.h文件中:

/* * The event structure itself */ struct input_event { struct timeval time; //事件发生的时间 __u16 type; //事件类型 __u16 code; //事件码 __s32 value; //事件值 }; /* *其中timeval结构体定义为: * struct timeval { * __kernel_time_t tv_sec; /* seconds 秒*/ * __kernel_suseconds_t tv_usec; /* microseconds 微秒*/ * }; * * */

注:水平有限,这贴仅作笔记使用,侵权联系删,有错请指出,也可以让本人学习。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有